{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "6a5899a2",
   "metadata": {
    "id": "6a5899a2"
   },
   "source": [
    "# 把movie文件夹下的imdb_processed.csv读取，分为训练集和测试集，训练集和测试集的特征，都单独写入一个文件，通过subword-nmt命令进行bpe分词"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "id": "f2d80123",
   "metadata": {
    "id": "f2d80123"
   },
   "outputs": [],
   "source": [
    "import pandas as pd\n",
    "import numpy as np\n",
    "import os\n",
    "from sklearn.model_selection import train_test_split\n",
    "\n",
    "# 读取数据\n",
    "df = pd.read_csv('movie/imdb_processed.csv')\n",
    "\n",
    "# 分割训练集和测试集\n",
    "train_df, test_df = train_test_split(df, test_size=0.2, random_state=42)\n",
    "\n",
    "# 创建目录（如果不存在）\n",
    "os.makedirs('movie/bpe', exist_ok=True)\n",
    "\n",
    "# 将训练集和测试集的文本写入文件\n",
    "train_df['processed'].to_csv('movie/bpe/train.txt', index=False, header=False)\n",
    "test_df['processed'].to_csv('movie/bpe/test.txt', index=False, header=False)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "id": "cced9810",
   "metadata": {
    "colab": {
     "base_uri": "https://localhost:8080/"
    },
    "id": "cced9810",
    "outputId": "4f6aafeb-1da7-42b5-eafe-050648cd06f2"
   },
   "outputs": [
    {
     "output_type": "stream",
     "name": "stdout",
     "text": [
      "/content\n"
     ]
    }
   ],
   "source": [
    "!pwd"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "id": "d248d26c",
   "metadata": {
    "id": "d248d26c"
   },
   "outputs": [],
   "source": [
    "# BPE（Byte Pair Encoding）是一种用于文本分词的子词编码方法 # 解释BPE的定义\n",
    "# 它通过统计文本中最常见的相邻字符对，并将其合并为一个新的符号，逐步构建子词单元 # 说明BPE的基本原理\n",
    "# 这种方法可以有效减少词表大小，同时处理未登录词（OOV）问题 # 说明BPE的优点\n",
    "# 在自然语言处理中，BPE常用于神经网络模型的分词预处理，提升模型对罕见词的泛化能力 # 说明BPE的应用场景\n"
   ]
  },
  {
   "cell_type": "code",
   "source": [
    "!pip install subword-nmt"
   ],
   "metadata": {
    "colab": {
     "base_uri": "https://localhost:8080/"
    },
    "id": "VSbEPe1nWKzO",
    "outputId": "aa5dbdb5-27db-407f-aa0d-7daab1f801df"
   },
   "id": "VSbEPe1nWKzO",
   "execution_count": 8,
   "outputs": [
    {
     "output_type": "stream",
     "name": "stdout",
     "text": [
      "Collecting subword-nmt\n",
      "  Downloading subword_nmt-0.3.8-py3-none-any.whl.metadata (9.2 kB)\n",
      "Collecting mock (from subword-nmt)\n",
      "  Downloading mock-5.2.0-py3-none-any.whl.metadata (3.1 kB)\n",
      "Requirement already satisfied: tqdm in /usr/local/lib/python3.11/dist-packages (from subword-nmt) (4.67.1)\n",
      "Downloading subword_nmt-0.3.8-py3-none-any.whl (27 kB)\n",
      "Downloading mock-5.2.0-py3-none-any.whl (31 kB)\n",
      "Installing collected packages: mock, subword-nmt\n",
      "Successfully installed mock-5.2.0 subword-nmt-0.3.8\n"
     ]
    }
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "id": "2678c093",
   "metadata": {
    "colab": {
     "base_uri": "https://localhost:8080/"
    },
    "id": "2678c093",
    "outputId": "bf79dea7-b5a8-4d67-e0e7-5179f3e42147"
   },
   "outputs": [
    {
     "output_type": "stream",
     "name": "stdout",
     "text": [
      "100% 8000/8000 [00:17<00:00, 465.00it/s]\n"
     ]
    }
   ],
   "source": [
    "# 使用subword-nmt进行BPE分词\n",
    "# 1. 学习BPE编码（在训练集上）\n",
    "# 学习bpe分词(很慢,学一次就好)\n",
    "# -i 选择学习的文件\n",
    "# -o 核心输出文件,分词需要用到imdb_bpe_code,生成的 imdb_bpe_code 文件包含了学习到的 BPE 操作规则。这些规则用于将单词分割成子词单元\n",
    "# --write-vocabulary 字典输出文件，imdb_bpe_vocab 文件包含了根据 BPE 规则生成的词汇表，列出了所有子词单元及其频率\n",
    "# -s 词表大小\n",
    "!subword-nmt learn-joint-bpe-and-vocab -i ./movie/bpe/train.txt -o ./movie/bpe/imdb_bpe_code --write-vocabulary ./movie/bpe/imdb_bpe_vocab -s 8000"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "id": "eb130500",
   "metadata": {
    "id": "eb130500"
   },
   "outputs": [],
   "source": [
    "# 2. 应用BPE编码到训练集和测试集\n",
    "!subword-nmt apply-bpe -c movie/bpe/imdb_bpe_code -i movie/bpe/train.txt -o movie/bpe/train.bpe.txt\n",
    "!subword-nmt apply-bpe -c movie/bpe/imdb_bpe_code -i movie/bpe/test.txt -o movie/bpe/test.bpe.txt\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "id": "672808d4",
   "metadata": {
    "id": "672808d4"
   },
   "outputs": [],
   "source": [
    "# # 3. 获取词汇表\n",
    "# !subword-nmt get-vocab < movie/bpe/imdb_bpe_vocab > movie/bpe/vocab.txt\n",
    "\n",
    "# print(\"BPE处理完成！\")\n",
    "# print(f\"训练集大小: {len(train_df)}\")\n",
    "# print(f\"测试集大小: {len(test_df)}\")\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "id": "afee52b3",
   "metadata": {
    "colab": {
     "base_uri": "https://localhost:8080/"
    },
    "id": "afee52b3",
    "outputId": "d88a5b0b-d772-4a6c-c8df-a5df9e15a9b0"
   },
   "outputs": [
    {
     "output_type": "stream",
     "name": "stdout",
     "text": [
      "词典大小: 8105\n",
      "前10个词条: [('[PAD]', 0), ('[BOS]', 1), ('[UNK]', 2), ('[EOS]', 3), ('.', 4), (',', 5), ('I', 6), ('-', 7), ('movie', 8), ('film', 9)]\n"
     ]
    }
   ],
   "source": [
    "# 读取BPE词汇表并构建词典\n",
    "vocab = {}\n",
    "special_tokens = {\n",
    "    \"[PAD]\": 0,  # 填充 token\n",
    "    \"[BOS]\": 1,  # begin of sentence\n",
    "    \"[UNK]\": 2,  # 未知 token\n",
    "    \"[EOS]\": 3,  # end of sentence\n",
    "}\n",
    "\n",
    "# 首先添加特殊标记\n",
    "vocab.update(special_tokens)\n",
    "\n",
    "# 读取BPE词汇表\n",
    "# 先将特殊标记的数量赋值给变量j，作为后续词汇表中子词的起始索引\n",
    "j = len(special_tokens)\n",
    "# 打开BPE生成的词汇表文件，读取每一行\n",
    "with open('movie/bpe/imdb_bpe_vocab', 'r', encoding='utf-8') as f:\n",
    "    # 遍历文件中的每一行，每行包含一个子词和其出现频率\n",
    "    for i, line in enumerate(f):\n",
    "        # 将每行按空格分割，得到子词token和出现次数count\n",
    "        token, count = line.strip().split(' ')\n",
    "        # 如果该子词不在已有的词典中（避免与特殊标记重复）\n",
    "        if token not in vocab:\n",
    "            # 将该子词加入词典，分配当前的索引j\n",
    "            vocab[token] = j\n",
    "            # 索引自增，为下一个新子词准备\n",
    "            j += 1\n",
    "\n",
    "print(f\"词典大小: {len(vocab)}\")\n",
    "print(f\"前10个词条: {list(vocab.items())[:10]}\")\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "id": "9d3ab3fb",
   "metadata": {
    "colab": {
     "base_uri": "https://localhost:8080/"
    },
    "id": "9d3ab3fb",
    "outputId": "df176170-bc97-4807-dc21-de3f21288c12"
   },
   "outputs": [
    {
     "output_type": "stream",
     "name": "stdout",
     "text": [
      "8101 movie/bpe/imdb_bpe_vocab\n"
     ]
    }
   ],
   "source": [
    "!wc -l movie/bpe/imdb_bpe_vocab"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "3a747c92",
   "metadata": {
    "id": "3a747c92"
   },
   "source": [
    "# Dataset"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "88a7ead6",
   "metadata": {
    "id": "88a7ead6"
   },
   "source": [
    "# Tokenizer"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "id": "6291049d",
   "metadata": {
    "id": "6291049d"
   },
   "outputs": [],
   "source": [
    "class Tokenizer:\n",
    "    def __init__(self, vocab):\n",
    "        \"\"\"\n",
    "        初始化分词器\n",
    "\n",
    "        参数:\n",
    "            vocab: 词汇表字典，将token映射到ID\n",
    "        \"\"\"\n",
    "        self.vocab = vocab #子词到id的映射\n",
    "        self.id_to_token = {v: k for k, v in vocab.items()} #id到子词的映射\n",
    "        self.pad_id = vocab[\"[PAD]\"] #填充token的id\n",
    "        self.bos_id = vocab[\"[BOS]\"]\n",
    "        self.eos_id = vocab[\"[EOS]\"]\n",
    "        self.unk_id = vocab[\"[UNK]\"]\n",
    "\n",
    "    def encode(self, text, max_length=None):\n",
    "        \"\"\"\n",
    "        将文本编码为ID序列\n",
    "\n",
    "        参数:\n",
    "            text: 输入文本，每次输入一个句子\n",
    "            max_length: 最大序列长度，如果指定则会进行截断或填充\n",
    "\n",
    "        返回:\n",
    "            token_ids: ID序列\n",
    "        \"\"\"\n",
    "        # 分词处理\n",
    "        tokens = text.split() #将文本按空格分词\n",
    "\n",
    "        # 添加开始标记\n",
    "        token_ids = [self.bos_id]\n",
    "\n",
    "        # 转换为ID\n",
    "        for token in tokens:\n",
    "            if token in self.vocab: #如果token在词典中，则直接添加id\n",
    "                token_ids.append(self.vocab[token])\n",
    "            else:\n",
    "                # 处理未知token，直接添加UNK标记\n",
    "                token_ids.append(self.unk_id)\n",
    "\n",
    "        # 添加结束标记\n",
    "        token_ids.append(self.eos_id)\n",
    "\n",
    "        # 处理序列长度\n",
    "        if max_length is not None:\n",
    "            if len(token_ids) > max_length:\n",
    "                # 截断序列\n",
    "                token_ids = token_ids[:max_length-1] + [self.eos_id]\n",
    "            else:\n",
    "                # 填充序列\n",
    "                token_ids = token_ids + [self.pad_id] * (max_length - len(token_ids))\n",
    "\n",
    "        return token_ids\n",
    "\n",
    "    def decode(self, token_ids):\n",
    "        \"\"\"\n",
    "        将ID序列解码为文本\n",
    "\n",
    "        参数:\n",
    "            token_ids: ID序列\n",
    "\n",
    "        返回:\n",
    "            text: 解码后的文本\n",
    "        \"\"\"\n",
    "        tokens = []\n",
    "        for id in token_ids:\n",
    "            if id in [self.pad_id, self.bos_id, self.eos_id]:\n",
    "                continue\n",
    "\n",
    "            # 根据给定的id，从id_to_token字典中获取对应的token，如果找不到则返回\"[UNK]\"表示未知词\n",
    "            token = self.id_to_token.get(id, \"[UNK]\")\n",
    "            tokens.append(token)\n",
    "\n",
    "        # 合并子词\n",
    "        text = \"\"\n",
    "        for token in tokens:\n",
    "            if token.endswith(\"@@\"):\n",
    "                text += token[:-2]  # 移除@@后缀\n",
    "            else:\n",
    "                text += token + \" \"\n",
    "\n",
    "        return text.strip()\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "6f4c3d2c",
   "metadata": {
    "id": "6f4c3d2c"
   },
   "source": [
    "# Dataset"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "id": "3f79b7bd",
   "metadata": {
    "id": "3f79b7bd"
   },
   "outputs": [],
   "source": [
    "import torch  # 导入PyTorch库\n",
    "from torch.utils.data import Dataset  # 导入Dataset基类\n",
    "import pandas as pd  # 导入pandas用于数据处理\n",
    "\n",
    "class IMDBDataset(Dataset):  # 定义IMDB数据集类，继承自PyTorch的Dataset\n",
    "    \"\"\"\n",
    "    IMDB数据集类，用于加载和处理IMDB电影评论数据\n",
    "    \"\"\"\n",
    "    def __init__(self, bpe_file, csv_file, vocab, max_length=512, mode='train'):  # 初始化方法，传入BPE文件、CSV文件、词表、最大长度和模式\n",
    "        \"\"\"\n",
    "        初始化数据集\n",
    "\n",
    "        参数:\n",
    "            bpe_file: 包含BPE处理后的文本文件路径\n",
    "            csv_file: 包含电影评论标签的CSV文件路径\n",
    "            vocab: 词汇表字典\n",
    "            max_length: 序列最大长度\n",
    "        \"\"\"\n",
    "        # 读取标签数据，根据mode决定读取哪部分数据\n",
    "        if mode == 'train':  # 如果是训练模式\n",
    "            self.labels = pd.read_csv(csv_file, nrows=40000)['label'].values  # 读取前40000行的标签\n",
    "        else:  # 如果是测试模式\n",
    "            df = pd.read_csv(csv_file)  # 读取整个CSV文件\n",
    "            self.labels = df.iloc[-10000:]['label'].values  # 取最后10000行的标签\n",
    "\n",
    "        self.texts = []  # 初始化文本列表\n",
    "        with open(bpe_file, 'r', encoding='utf-8') as f:  # 打开BPE处理后的文本文件\n",
    "            self.texts = [line.strip() for line in f]  # 读取每一行并去除首尾空白符\n",
    "\n",
    "        assert len(self.texts) == len(self.labels), \"文本和标签数量不匹配\"  # 检查文本和标签数量是否一致\n",
    "\n",
    "        self.tokenizer = Tokenizer(vocab)  # 创建分词器对象\n",
    "        self.max_length = max_length  # 保存最大长度参数\n",
    "\n",
    "    def __len__(self):  # 定义获取数据集大小的方法\n",
    "        \"\"\"返回数据集大小\"\"\"\n",
    "        return len(self.texts)  # 返回文本数量\n",
    "\n",
    "    def __getitem__(self, idx):  # 定义获取单个样本的方法\n",
    "        \"\"\"\n",
    "        获取指定索引的样本\n",
    "\n",
    "        参数:\n",
    "            idx: 样本索引\n",
    "\n",
    "        返回:\n",
    "            tokens: 分词后的评论文本\n",
    "            label: 情感标签 (0表示负面, 1表示正面)\n",
    "        \"\"\"\n",
    "        text = self.texts[idx]  # 获取指定索引的文本\n",
    "        label = self.labels[idx]  # 获取指定索引的标签\n",
    "\n",
    "        token_ids = self.tokenizer.encode(text, max_length=500)  # 对文本进行编码，得到token id序列\n",
    "\n",
    "        return {  # 返回一个字典，包含token_ids和label\n",
    "            'token_ids': token_ids,\n",
    "            'label': label\n",
    "        }\n",
    "\n",
    "train_ds = IMDBDataset(bpe_file='movie/bpe/train.bpe.txt', csv_file='movie/imdb_processed.csv', vocab=vocab, mode='train')  # 创建训练集对象\n",
    "test_ds = IMDBDataset(bpe_file='movie/bpe/test.bpe.txt', csv_file='movie/imdb_processed.csv', vocab=vocab, mode='test')  # 创建测试集对象\n",
    "\n",
    "# print(train_ds[0])  # 打印训练集第一个样本（可选）\n",
    "# print(test_ds[0])  # 打印测试集第一个样本（可选）"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "2e718618",
   "metadata": {
    "id": "2e718618"
   },
   "source": [
    "# DataLoader"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "id": "9e17a21c",
   "metadata": {
    "colab": {
     "base_uri": "https://localhost:8080/"
    },
    "id": "9e17a21c",
    "outputId": "fb792638-0fd9-4f76-e109-3528a6fe86f3"
   },
   "outputs": [
    {
     "output_type": "stream",
     "name": "stdout",
     "text": [
      "训练集DataLoader批次数量: 1250\n",
      "验证集DataLoader批次数量: 313\n",
      "批次中的token_ids形状: torch.Size([32, 500])\n",
      "批次中的标签形状: torch.Size([32, 1])\n"
     ]
    },
    {
     "output_type": "execute_result",
     "data": {
      "text/plain": [
       "tensor([[   1, 5337,   37,  ...,    0,    0,    0],\n",
       "        [   1,   29,  394,  ...,    0,    0,    0],\n",
       "        [   1, 1823,  637,  ...,    0,    0,    0],\n",
       "        ...,\n",
       "        [   1,   29,  194,  ...,    0,    0,    0],\n",
       "        [   1, 1823,  493,  ...,    0,    0,    0],\n",
       "        [   1,  111, 1594,  ...,    0,    0,    0]])"
      ]
     },
     "metadata": {},
     "execution_count": 19
    }
   ],
   "source": [
    "import torch  # 导入PyTorch库\n",
    "from torch.utils.data import Dataset, DataLoader  # 导入Dataset和DataLoader\n",
    "from torch.nn.utils.rnn import pad_sequence  # 导入pad_sequence用于序列填充\n",
    "\n",
    "def collate_fn(batch, pad_id=0):  # 定义批处理整理函数\n",
    "    \"\"\"\n",
    "    数据批次整理函数\n",
    "    参数:\n",
    "        batch: 批次数据\n",
    "        pad_id: 填充ID\n",
    "    返回:\n",
    "        token_ids: 填充后的token_ids张量\n",
    "        labels: 标签张量\n",
    "    \"\"\"\n",
    "    token_ids = [torch.tensor(item['token_ids'], dtype=torch.long) for item in batch]  # 将每个样本的token_ids转为LongTensor\n",
    "    labels = torch.tensor([item['label'] for item in batch], dtype=torch.float).unsqueeze(1)  # 将标签转为FloatTensor并增加一维\n",
    "    padded_token_ids = pad_sequence(token_ids, batch_first=True, padding_value=pad_id)  # 对token_ids进行填充，batch维度在第一维\n",
    "    return padded_token_ids, labels  # 返回填充后的token_ids和标签\n",
    "\n",
    "def create_dataloaders(train_ds, test_ds, batch_size=4):  # 定义创建DataLoader的函数\n",
    "    \"\"\"\n",
    "    创建训练集和验证集的DataLoader\n",
    "    参数:\n",
    "        train_ds: 训练集数据集对象\n",
    "        test_ds: 测试集数据集对象\n",
    "        batch_size: 批次大小\n",
    "    返回:\n",
    "        train_dataloader: 训练集DataLoader\n",
    "        val_dataloader: 验证集DataLoader\n",
    "    \"\"\"\n",
    "    train_dataloader = DataLoader(  # 创建训练集DataLoader\n",
    "        train_ds,  # 训练集数据集\n",
    "        batch_size=batch_size,  # 批次大小\n",
    "        shuffle=True,  # 打乱数据\n",
    "        collate_fn=collate_fn  # 使用自定义的collate_fn\n",
    "    )\n",
    "    val_dataloader = DataLoader(  # 创建验证集DataLoader\n",
    "        test_ds,  # 测试集数据集\n",
    "        batch_size=batch_size,  # 批次大小\n",
    "        shuffle=False,  # 不打乱数据\n",
    "        collate_fn=collate_fn  # 使用自定义的collate_fn\n",
    "    )\n",
    "    return train_dataloader, val_dataloader  # 返回训练集和验证集的DataLoader\n",
    "\n",
    "batch_size = 32  # 设置批次大小为32\n",
    "train_dataloader, val_dataloader = create_dataloaders(  # 调用函数创建DataLoader\n",
    "    train_ds=train_ds,  # 传入训练集\n",
    "    test_ds=test_ds,  # 传入测试集\n",
    "    batch_size=batch_size  # 传入批次大小\n",
    ")\n",
    "\n",
    "print(f\"训练集DataLoader批次数量: {len(train_dataloader)}\")  # 打印训练集DataLoader的批次数量\n",
    "print(f\"验证集DataLoader批次数量: {len(val_dataloader)}\")  # 打印验证集DataLoader的批次数量\n",
    "\n",
    "sample_batch = next(iter(train_dataloader))  # 获取训练集的第一个批次\n",
    "token_ids, labels = sample_batch  # 拆分出token_ids和labels\n",
    "print(f\"批次中的token_ids形状: {token_ids.shape}\")  # 打印token_ids的形状\n",
    "print(f\"批次中的标签形状: {labels.shape}\")  # 打印labels的形状\n",
    "\n",
    "token_ids  # 输出token_ids张量"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "81586740",
   "metadata": {
    "id": "81586740"
   },
   "source": [
    "# 搭建模型"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "id": "7e28fc1b",
   "metadata": {
    "colab": {
     "base_uri": "https://localhost:8080/"
    },
    "id": "7e28fc1b",
    "outputId": "10d39396-8ed5-40c6-da75-bfdef941e0ef"
   },
   "outputs": [
    {
     "output_type": "stream",
     "name": "stdout",
     "text": [
      "模型结构:\n",
      "SentimentClassifier(\n",
      "  (embedding): Embedding(8105, 16)\n",
      "  (lstm): LSTM(16, 128, batch_first=True)\n",
      "  (fc1): Linear(in_features=128, out_features=128, bias=True)\n",
      "  (fc): Linear(in_features=128, out_features=1, bias=True)\n",
      "  (dropout): Dropout(p=0.3, inplace=False)\n",
      ")\n",
      "单层单向lstm模型参数数量: 221,073\n"
     ]
    }
   ],
   "source": [
    "import torch\n",
    "import torch.nn as nn\n",
    "import torch.nn.functional as F\n",
    "\n",
    "class SentimentClassifier(nn.Module):\n",
    "    def __init__(self, vocab_size, embedding_dim=16, hidden_dim=128, output_dim=1,\n",
    "                 lstm_layers=1, bidirectional=False, dropout_rate=0.3):\n",
    "        super().__init__()\n",
    "\n",
    "        # 嵌入层\n",
    "        self.embedding = nn.Embedding(vocab_size, embedding_dim)\n",
    "\n",
    "        # 设置lstm层\n",
    "        self.lstm = nn.LSTM(embedding_dim, hidden_dim,\n",
    "                         num_layers=lstm_layers, # 层数\n",
    "                         bidirectional=bidirectional, # 是否双向\n",
    "                         batch_first=True,\n",
    "                         dropout=dropout_rate if lstm_layers > 1 else 0)\n",
    "\n",
    "        # 确定输出维度\n",
    "        fc_input_dim = hidden_dim * 2 if bidirectional else hidden_dim\n",
    "\n",
    "        # 增加一个fc层，输入是fc_input_dim，输出是hidden_dim\n",
    "        self.fc1 = nn.Linear(fc_input_dim, hidden_dim)\n",
    "\n",
    "        # 全连接层\n",
    "        self.fc = nn.Linear(hidden_dim, output_dim)\n",
    "\n",
    "        # Dropout层，防止过拟合\n",
    "        self.dropout = nn.Dropout(dropout_rate)\n",
    "\n",
    "    def forward(self, x):\n",
    "        # x形状: [batch_size, seq_len]\n",
    "\n",
    "        # 通过嵌入层\n",
    "        embedded = self.embedding(x)  # [batch_size, seq_len, embedding_dim]\n",
    "\n",
    "        # 通过lstm层\n",
    "        outputs, hidden = self.lstm(embedded)\n",
    "\n",
    "        # print(f'outputs.shape: {outputs.shape}')\n",
    "        # print(f'hidden.shape: {hidden.shape}')\n",
    "\n",
    "        # 取最后一个时间步的输出 (这也是为什么要设置padding_first=True的原因)\n",
    "        x = outputs[:, -1, :]\n",
    "\n",
    "        # 应用dropout\n",
    "        x = self.dropout(x)\n",
    "        x = self.fc1(x)\n",
    "        x = self.fc(x)\n",
    "\n",
    "        return x\n",
    "\n",
    "# 初始化模型\n",
    "model = SentimentClassifier(vocab_size=len(vocab), lstm_layers=1, bidirectional=False)\n",
    "print(f\"模型结构:\\n{model}\")\n",
    "\n",
    "# 打印模型参数数量\n",
    "def count_parameters(model):\n",
    "    return sum(p.numel() for p in model.parameters() if p.requires_grad)\n",
    "\n",
    "print(f\"单层单向lstm模型参数数量: {count_parameters(model):,}\")\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 22,
   "id": "f6f803c5",
   "metadata": {
    "colab": {
     "base_uri": "https://localhost:8080/"
    },
    "id": "f6f803c5",
    "outputId": "c589a8d8-8f8c-4df5-fd16-dee41b2457d6"
   },
   "outputs": [
    {
     "output_type": "stream",
     "name": "stdout",
     "text": [
      "使用设备: cuda\n",
      "输入形状: torch.Size([32, 500])\n",
      "输出形状: torch.Size([32, 1])\n"
     ]
    }
   ],
   "source": [
    "# 设置设备\n",
    "device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')\n",
    "print(f\"使用设备: {device}\")\n",
    "# 验证模型的前向计算\n",
    "# 从训练数据中获取一个批次的样本\n",
    "sample_batch, sample_labels = next(iter(train_dataloader))\n",
    "print(f\"输入形状: {sample_batch.shape}\")\n",
    "\n",
    "# 将样本移动到设备上\n",
    "sample_batch = sample_batch.to(device)\n",
    "\n",
    "# Move the model to the device\n",
    "model = model.to(device)\n",
    "\n",
    "# 进行前向计算\n",
    "with torch.no_grad():\n",
    "    outputs = model(sample_batch)\n",
    "    print(f\"输出形状: {outputs.shape}\")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "cbc05baa",
   "metadata": {
    "id": "cbc05baa"
   },
   "source": [
    "# 训练，画图，评估"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 23,
   "id": "175bd35f",
   "metadata": {
    "colab": {
     "base_uri": "https://localhost:8080/",
     "height": 240,
     "referenced_widgets": [
      "e450640c0156400e89c039962ca47e70",
      "ad72f8592a6640fba291ad62b752f6d1",
      "875db77a536148f5acf07ed08e9b1058",
      "80243981439b4df2b5790745062bb3b7",
      "ead3412cfdb64bf6a8845747db19d439",
      "e75b3ab288bb41f887a1824699458c20",
      "12bbf7b0a1894c7e890bd4570a86adf0",
      "95ca9086b07043cdb52f1bd4f435496f",
      "d932478815ad4ee58a672fb1ee59e121",
      "6675b30a4ef946e399e9ccdb98b004ea",
      "ecc38d1eb03148f1b8115c36e80e279f"
     ]
    },
    "id": "175bd35f",
    "outputId": "71a32e5f-dc53-4896-ab37-6ec7fe7f32f4"
   },
   "outputs": [
    {
     "output_type": "stream",
     "name": "stdout",
     "text": [
      "模型结构:\n",
      "SentimentClassifier(\n",
      "  (embedding): Embedding(8105, 16)\n",
      "  (lstm): LSTM(16, 128, batch_first=True, bidirectional=True)\n",
      "  (fc1): Linear(in_features=256, out_features=128, bias=True)\n",
      "  (fc): Linear(in_features=128, out_features=1, bias=True)\n",
      "  (dropout): Dropout(p=0.3, inplace=False)\n",
      ")\n",
      "训练开始，共25000步\n"
     ]
    },
    {
     "output_type": "display_data",
     "data": {
      "text/plain": [
       "  0%|          | 0/25000 [00:00<?, ?it/s]"
      ],
      "application/vnd.jupyter.widget-view+json": {
       "version_major": 2,
       "version_minor": 0,
       "model_id": "e450640c0156400e89c039962ca47e70"
      }
     },
     "metadata": {}
    },
    {
     "output_type": "stream",
     "name": "stdout",
     "text": [
      "早停触发! 最佳验证准确率(如果是回归，这里是损失): 50.2300\n",
      "早停: 在500 步\n"
     ]
    }
   ],
   "source": [
    "from my_deeplearning_train import train_two_classification_model, evaluate_two_classification_model,plot_learning_curves,EarlyStopping,ModelSaver\n",
    "\n",
    "model = SentimentClassifier(vocab_size=len(vocab), lstm_layers=1, bidirectional=True)\n",
    "print(f\"模型结构:\\n{model}\")\n",
    "\n",
    "# 定义损失函数和优化器\n",
    "criterion = nn.BCEWithLogitsLoss() #WithLogitsLoss代表的含义是：把输出结果通过sigmoid函数，然后计算损失\n",
    "optimizer = torch.optim.Adam(model.parameters(), lr=0.001)\n",
    "# 将模型移动到设备上\n",
    "model = model.to(device)\n",
    "\n",
    "\n",
    "# 训练参数\n",
    "num_epochs = 20\n",
    "eval_step = 100\n",
    "\n",
    "# 训练模型\n",
    "# 创建早停和模型保存器\n",
    "early_stopping = EarlyStopping(patience=5, delta=0.001)\n",
    "model_saver = ModelSaver(save_dir='weights')\n",
    "\n",
    "model, record_dict = train_two_classification_model(\n",
    "    model=model,\n",
    "    train_loader=train_dataloader,\n",
    "    val_loader=val_dataloader,\n",
    "    criterion=criterion,\n",
    "    optimizer=optimizer,\n",
    "    device=device,\n",
    "    num_epochs=num_epochs,\n",
    "    eval_step=eval_step,\n",
    "    early_stopping=early_stopping,\n",
    "    model_saver=model_saver\n",
    ")\n",
    "\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 24,
   "id": "d91eae27",
   "metadata": {
    "colab": {
     "base_uri": "https://localhost:8080/",
     "height": 465
    },
    "id": "d91eae27",
    "outputId": "18ca0dac-21d7-4986-b87b-1f86b9bc51ee"
   },
   "outputs": [
    {
     "output_type": "display_data",
     "data": {
      "text/plain": [
       "<Figure size 1000x500 with 2 Axes>"
      ],
      "image/png": "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LYqKiqBWq2EwGNDV1YWOjg4oFArk5+fj1ltv7fe+hYWF0Gq11uTPVQ1qTdU777yDuLg4yGQypKen48iRI5c8d+bMmWAYps/HwoULreewLIvVq1cjIiICcrkcGRkZOHPmTK/HiYuL6/MYr776aq9zjh8/jmuuuQYymQwxMTFYt27dYL49Qq6IKx0ZEepzyUXRydZmFVpq32tPDGMub+Djw4bE+IYbbgDLsti+fTsqKirw008/YcmSJQCAZ555Bt988w1eeeUV/PTTT8jPz0dqaip0Op2jfmq9fPjhh8jJycHUqVPxxRdfYPTo0Th06BAA4IUXXsDJkyexcOFCfP/990hOTsY333zjlLgIsdXxylZUtXRCIRFiZkLoFc9nGIZKAIljuckYBThvnCorK8P111+PtLQ0fP3118jLy8M777wDANbHk8vll7z/5W5zJTYnVV988QVWrlyJ559/HseOHcPYsWMxd+5c1NfX93v+1q1bUVNTY/0oKCiAUCjslY2uW7cOb731Ft577z0cPnwYPj4+mDt3Lrq6endNW7NmTa/Hevzxx623qdVqZGZmIjY2Fnl5eXjttdfwwgsv4P3337f1WyTkigov06SC06tZBZUAeh2ZTIabb74Zn376KT7//HMkJCRg/PjxAMyLce+77z7cdNNNSE1NhUqlQllZmV2eNykpCb/++is0Go312IEDByAQCJCQkGA9dtVVV2HVqlU4ePAgUlJS8Nlnn1lvGz16NFasWIHdu3fj5ptvxocffmiX2AixN67r33WJVy794ySpuGYVbQ6LixB34KxxKi8vDyaTCW+88QauvvpqjB49GtXVvWfz0tLSsHfv3n7vP2rUKMjl8kve7ipsTqrWr1+PZcuW4f7770dycjLee+89KBQKbNq0qd/zg4KCoFKprB/Z2dlQKBTWpIplWWzYsAF/+tOfsGjRIqSlpeHjjz9GdXV1n80slUplr8fqWd7y6aefQqfTYdOmTRgzZgzuuOMOPPHEE1i/fr2t3yIhV3Sl9VScFNoE2KstWbIE27dvx6ZNm6xX/wDzALF161bk5+fj119/xV133dWnA9NQnlMmk+Hee+9FQUEBfvjhBzz++OO45557EB4ejtLSUqxatQo5OTk4f/48du/ejTNnziApKQmdnZ1Yvnw59u3bh/Pnz+PAgQPIzc3tteaKEFfBsiyyCsxJ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SkQEK308KiIiorFLLpUgObq3Cm98WCDiwgJ9OCIi/8agityWMzkCUSFi6VaAqX9EREQjQd/zMddTEXkXgypym1Qi4L7MOPt9BlVERES+1zcVn01/ibyLQRV5hK0RMMD1VERERCNB34ucNzOoIvIqBlXkEZkJochMCEWAXMKrYURERCNARkIoxqnkmBgZhCl91lcRkeexpDp5hCAI2PxYNvSGbi6EJSIiGgHUAXLsXnsnZBIBEong6+EQ+TUGVeQxoYFyhAayUzsREdFIERXCarxEw4Hpf0RERERERG5gUEVEREREROQGBlVERERERERuYFBFRERERETkBgZVREREREREbmBQRURERERE5AYGVURERERERG5gUEVEREREROQGBlVERERERERuYFBFRETkorfffhuZmZlQq9VQq9XIycnB559/bn++q6sLq1evRkREBIKDg7F06VI0NDT4cMREROQNDKqIiIhclJCQgNdeew0lJSU4evQo5s2bh7y8PJw6dQoAsHbtWnzyySf4+9//jr1796K2thYPPvigj0dNRESeJvP1AIiIiEar++67z+H+yy+/jLfffhsHDx5EQkIC/vKXv+D999/HvHnzAADvvvsu0tLScPDgQdxyyy2+GDIREXkBgyoiIiIPMJvN+Pvf/w69Xo+cnByUlJTAZDIhNzfXvk1qairGjx+PAwcODBhUGQwGGAwG+32tVgsAMJlMMJlMTo/Lto8r+xIRjWXOfG4yqCIiInJDWVkZcnJy0NXVheDgYHz88cdIT09HaWkpFAoFwsLCHLaPiYlBfX39gMd79dVX8cILL1z3+O7du6FSqVweZ1FRkcv7EhGNRR0dHUPelkFVH1arFUDvVUFnmUwmdHR0QKvVQi6Xe3JoRER+zfa5a/scHk1SUlJQWlqKtrY2bN26FY8++ij27t3r8vEKCgqQn59vv9/W1obx48cjJycHISEhTh/PZDLhyy+/xN13381zExGRE3Q6HYChnZsYVPVh+8ElJib6eCRERGOTTqdDaGior4fhFIVCgeTkZABAVlYWjhw5gt/+9rdYvnw5jEYjWltbHWarGhoaEBsbO+DxlEollEql/b4t4Jw4caJ33gAREd3QUM5NDKr6iIuLQ3V1NUJCQiAIgtP7a7VaJCYmorq6Gmq12gsjJCLyT1arFTqdDnFxcb4eitssFgsMBgOysrIgl8uxZ88eLF26FABQUVGBqqoq5OTkDPl4PDcREfmGM+cmBlV9SCQSJCQkuH0cW78SIiIautE2QwWIqXr33nsvxo8fD51Oh/fffx/FxcUoLCxEaGgoHnvsMeTn5yM8PBxqtRpPP/00cnJynKr8x3MTEZHvDPXcxKCKiIjIRY2NjVi5ciXq6uoQGhqKzMxMFBYWYsGCBQCA3/zmN5BIJFi6dCkMBgMWLVqEP/zhDz4eNREReZpgHY2rgkcorVaL0NBQtLW18WogERGNCDw3ERF5n8TXA/AnSqUS69evd1hgTERE5Es8NxEReR9nqoiIiIiIiNzAmSoiIiIiIiI3MKgiIiIiIiJyA4MqIiIiIiIiNzCo8hJBELBt2zZfD4OIiAgAz0tERN7EoMoNb731FpKSkhAQEIDs7GwcPnzY10MiIqIxjOclIiLfYFDlog8//BD5+flYv349jh07hhkzZmDRokVobGz09dCIiGgM4nmJiMh3GFS56I033sATTzyBVatWIT09He+88w5UKhU2bdrU7/br16+HRqPBiRMnhnmkREQ0FvC8RETkOwyqXGA0GlFSUoLc3Fz7YxKJBLm5uThw4IDDtlarFU8//TT++te/4quvvkJmZuZwD5eIiPwcz0tERL4l8/UARqPm5maYzWbExMQ4PB4TE4Py8nL7/e7ubvzwhz/Et99+i/379yM+Pn64h0pERGMAz0tERL7FoMqL1q5dC6VSiYMHDyIyMtLXwyEiojGO5yUiIu9g+p8LIiMjIZVK0dDQ4PB4Q0MDYmNj7fcXLFiAmpoaFBYWDvcQiYhoDOF5iYjItxhUuUChUCArKwt79uyxP2axWLBnzx7k5OTYH7v//vvx/vvv4/HHH8cHH3zgi6ESEdEYwPMSEZFvMf3PRfn5+Xj00UcxZ84c3HzzzXjzzTeh1+uxatUqh+0eeOABbN68GY888ghkMhkeeughH42YiIj8Gc9LRES+w6DKRcuXL0dTUxOee+451NfXY+bMmdi1a9d1i4QB4KGHHoLFYsEjjzwCiUSCBx980AcjJiIif8bzEhGR7whWq9Xq60EQERERERGNVlxTRURERERE5AYGVURERERERG5gUEVEREREROQGBlVERERERERuYFBFRERERETkBgZVREREREREbmBQRURERERE5AYGVURERERERG5gUEU0yvzoRz/CkiVLfD0MIiIiO56baKxjUEVEREREROQGBlVEI9TWrVuRkZGBwMBAREREIDc3F7/4xS/w3nvvYfv27RAEAYIgoLi4GABQXV2NZcuWISwsDOHh4cjLy0NlZaX9eLariC+88AKioqKgVqvx05/+FEaj0TdvkIiIRh2em4j6J/P1AIjoenV1dXj44YexYcMGPPDAA9DpdPjqq6+wcuVKVFVVQavV4t133wUAhIeHw2QyYdGiRcjJycFXX30FmUyGX//617jnnntw4sQJKBQKAMCePXsQEBCA4uJiVFZWYtWqVYiIiMDLL7/sy7dLRESjAM9NRANjUEU0AtXV1aG7uxsPPvggJkyYAADIyMgAAAQGBsJgMCA2Nta+/f/8z//AYrHgz3/+MwRBAAC8++67CAsLQ3FxMRYuXAgAUCgU2LRpE1QqFaZNm4YXX3wRv/jFL/DSSy9BIuHENRERDYznJqKB8S+VaASaMWMG5s+fj4yMDPzLv/wLNm7ciKtXrw64/fHjx3Hu3DmEhIQgODgYwcHBCA8PR1dXF86fP+9wXJVKZb+fk5OD9vZ2VFdXe/X9EBHR6MdzE9HAOFNFNAJJpVIUFRXhm2++we7du/H73/8ev/zlL3Ho0KF+t29vb0dWVha2bNly3XNRUVHeHi4REY0BPDcRDYxBFdEIJQgC5s6di7lz5+K5557DhAkT8PHHH0OhUMBsNjtsO3v2bHz44YeIjo6GWq0e8JjHjx9HZ2cnAgMDAQAHDx5EcHAwEhMTvfpeiIjIP/DcRNQ/pv8RjUCHDh3CK6+8gqNHj6KqqgofffQRmpqakJaWhqSkJJw4cQIVFRVobm6GyWTCihUrEBkZiby8PHz11Ve4ePEiiouL8fOf/xyXL1+2H9doNOKxxx7D6dOnsXPnTqxfvx5r1qxhzjoREQ2K5yaigXGmimgEUqvV2LdvH958801otVpMmDAB//Vf/4V7770Xc+bMQXFxMebMmYP29nZ8+eWXuOuuu7Bv3z6sW7cODz74IHQ6HeLj4zF//nyHq4Pz58/HlClTcMcdd8BgMODhhx/G888/77s3SkREowbPTUQDE6xWq9XXgyAi7/vRj36E1tZWbNu2zddDISIiAsBzE/kPzqsSERERERG5gUEVERERERGRG5j+R0RERERE5AbOVBEREREREbmBQRUREREREZEbGFQRERERERG5gUEVERERERGRGxhUERERERERuYFBFRERERERkRsYVBEREREREbmBQRUREREREZEbGFQRERERERG54f8DU5h0xK7bKgsAAAAASUVORK5CYII=\n"
     },
     "metadata": {}
    }
   ],
   "source": [
    "# 绘制学习曲线\n",
    "plot_learning_curves(record_dict,sample_step=100)\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 26,
   "id": "3075fd61",
   "metadata": {
    "colab": {
     "base_uri": "https://localhost:8080/"
    },
    "id": "3075fd61",
    "outputId": "4afc0b8c-5d9a-44df-f1b0-3c977bf01be6"
   },
   "outputs": [
    {
     "output_type": "stream",
     "name": "stdout",
     "text": [
      "测试集准确率: 49.89%, 测试集损失: 0.6934\n"
     ]
    }
   ],
   "source": [
    "\n",
    "\n",
    "# 在测试集上评估最终模型\n",
    "test_acc, test_loss = evaluate_two_classification_model(model, val_dataloader, device, criterion)\n",
    "print(f\"测试集准确率: {test_acc:.2f}%, 测试集损失: {test_loss:.4f}\")"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.12.3"
  },
  "colab": {
   "provenance": [],
   "gpuType": "T4"
  },
  "accelerator": "GPU",
  "widgets": {
   "application/vnd.jupyter.widget-state+json": {
    "e450640c0156400e89c039962ca47e70": {
     "model_module": "@jupyter-widgets/controls",
     "model_name": "HBoxModel",
     "model_module_version": "1.5.0",
     "state": {
      "_dom_classes": [],
      "_model_module": "@jupyter-widgets/controls",
      "_model_module_version": "1.5.0",
      "_model_name": "HBoxModel",
      "_view_count": null,
      "_view_module": "@jupyter-widgets/controls",
      "_view_module_version": "1.5.0",
      "_view_name": "HBoxView",
      "box_style": "",
      "children": [
       "IPY_MODEL_ad72f8592a6640fba291ad62b752f6d1",
       "IPY_MODEL_875db77a536148f5acf07ed08e9b1058",
       "IPY_MODEL_80243981439b4df2b5790745062bb3b7"
      ],
      "layout": "IPY_MODEL_ead3412cfdb64bf6a8845747db19d439"
     }
    },
    "ad72f8592a6640fba291ad62b752f6d1": {
     "model_module": "@jupyter-widgets/controls",
     "model_name": "HTMLModel",
     "model_module_version": "1.5.0",
     "state": {
      "_dom_classes": [],
      "_model_module": "@jupyter-widgets/controls",
      "_model_module_version": "1.5.0",
      "_model_name": "HTMLModel",
      "_view_count": null,
      "_view_module": "@jupyter-widgets/controls",
      "_view_module_version": "1.5.0",
      "_view_name": "HTMLView",
      "description": "",
      "description_tooltip": null,
      "layout": "IPY_MODEL_e75b3ab288bb41f887a1824699458c20",
      "placeholder": "​",
      "style": "IPY_MODEL_12bbf7b0a1894c7e890bd4570a86adf0",
      "value": "  2%"
     }
    },
    "875db77a536148f5acf07ed08e9b1058": {
     "model_module": "@jupyter-widgets/controls",
     "model_name": "FloatProgressModel",
     "model_module_version": "1.5.0",
     "state": {
      "_dom_classes": [],
      "_model_module": "@jupyter-widgets/controls",
      "_model_module_version": "1.5.0",
      "_model_name": "FloatProgressModel",
      "_view_count": null,
      "_view_module": "@jupyter-widgets/controls",
      "_view_module_version": "1.5.0",
      "_view_name": "ProgressView",
      "bar_style": "danger",
      "description": "",
      "description_tooltip": null,
      "layout": "IPY_MODEL_95ca9086b07043cdb52f1bd4f435496f",
      "max": 25000,
      "min": 0,
      "orientation": "horizontal",
      "style": "IPY_MODEL_d932478815ad4ee58a672fb1ee59e121",
      "value": 500
     }
    },
    "80243981439b4df2b5790745062bb3b7": {
     "model_module": "@jupyter-widgets/controls",
     "model_name": "HTMLModel",
     "model_module_version": "1.5.0",
     "state": {
      "_dom_classes": [],
      "_model_module": "@jupyter-widgets/controls",
      "_model_module_version": "1.5.0",
      "_model_name": "HTMLModel",
      "_view_count": null,
      "_view_module": "@jupyter-widgets/controls",
      "_view_module_version": "1.5.0",
      "_view_name": "HTMLView",
      "description": "",
      "description_tooltip": null,
      "layout": "IPY_MODEL_6675b30a4ef946e399e9ccdb98b004ea",
      "placeholder": "​",
      "style": "IPY_MODEL_ecc38d1eb03148f1b8115c36e80e279f",
      "value": " 500/25000 [00:23&lt;07:08, 57.13it/s, epoch=0, loss=0.6984, acc=40.62%, val_loss=0.6941, val_acc=49.99%]"
     }
    },
    "ead3412cfdb64bf6a8845747db19d439": {
     "model_module": "@jupyter-widgets/base",
     "model_name": "LayoutModel",
     "model_module_version": "1.2.0",
     "state": {
      "_model_module": "@jupyter-widgets/base",
      "_model_module_version": "1.2.0",
      "_model_name": "LayoutModel",
      "_view_count": null,
      "_view_module": "@jupyter-widgets/base",
      "_view_module_version": "1.2.0",
      "_view_name": "LayoutView",
      "align_content": null,
      "align_items": null,
      "align_self": null,
      "border": null,
      "bottom": null,
      "display": null,
      "flex": null,
      "flex_flow": null,
      "grid_area": null,
      "grid_auto_columns": null,
      "grid_auto_flow": null,
      "grid_auto_rows": null,
      "grid_column": null,
      "grid_gap": null,
      "grid_row": null,
      "grid_template_areas": null,
      "grid_template_columns": null,
      "grid_template_rows": null,
      "height": null,
      "justify_content": null,
      "justify_items": null,
      "left": null,
      "margin": null,
      "max_height": null,
      "max_width": null,
      "min_height": null,
      "min_width": null,
      "object_fit": null,
      "object_position": null,
      "order": null,
      "overflow": null,
      "overflow_x": null,
      "overflow_y": null,
      "padding": null,
      "right": null,
      "top": null,
      "visibility": null,
      "width": null
     }
    },
    "e75b3ab288bb41f887a1824699458c20": {
     "model_module": "@jupyter-widgets/base",
     "model_name": "LayoutModel",
     "model_module_version": "1.2.0",
     "state": {
      "_model_module": "@jupyter-widgets/base",
      "_model_module_version": "1.2.0",
      "_model_name": "LayoutModel",
      "_view_count": null,
      "_view_module": "@jupyter-widgets/base",
      "_view_module_version": "1.2.0",
      "_view_name": "LayoutView",
      "align_content": null,
      "align_items": null,
      "align_self": null,
      "border": null,
      "bottom": null,
      "display": null,
      "flex": null,
      "flex_flow": null,
      "grid_area": null,
      "grid_auto_columns": null,
      "grid_auto_flow": null,
      "grid_auto_rows": null,
      "grid_column": null,
      "grid_gap": null,
      "grid_row": null,
      "grid_template_areas": null,
      "grid_template_columns": null,
      "grid_template_rows": null,
      "height": null,
      "justify_content": null,
      "justify_items": null,
      "left": null,
      "margin": null,
      "max_height": null,
      "max_width": null,
      "min_height": null,
      "min_width": null,
      "object_fit": null,
      "object_position": null,
      "order": null,
      "overflow": null,
      "overflow_x": null,
      "overflow_y": null,
      "padding": null,
      "right": null,
      "top": null,
      "visibility": null,
      "width": null
     }
    },
    "12bbf7b0a1894c7e890bd4570a86adf0": {
     "model_module": "@jupyter-widgets/controls",
     "model_name": "DescriptionStyleModel",
     "model_module_version": "1.5.0",
     "state": {
      "_model_module": "@jupyter-widgets/controls",
      "_model_module_version": "1.5.0",
      "_model_name": "DescriptionStyleModel",
      "_view_count": null,
      "_view_module": "@jupyter-widgets/base",
      "_view_module_version": "1.2.0",
      "_view_name": "StyleView",
      "description_width": ""
     }
    },
    "95ca9086b07043cdb52f1bd4f435496f": {
     "model_module": "@jupyter-widgets/base",
     "model_name": "LayoutModel",
     "model_module_version": "1.2.0",
     "state": {
      "_model_module": "@jupyter-widgets/base",
      "_model_module_version": "1.2.0",
      "_model_name": "LayoutModel",
      "_view_count": null,
      "_view_module": "@jupyter-widgets/base",
      "_view_module_version": "1.2.0",
      "_view_name": "LayoutView",
      "align_content": null,
      "align_items": null,
      "align_self": null,
      "border": null,
      "bottom": null,
      "display": null,
      "flex": null,
      "flex_flow": null,
      "grid_area": null,
      "grid_auto_columns": null,
      "grid_auto_flow": null,
      "grid_auto_rows": null,
      "grid_column": null,
      "grid_gap": null,
      "grid_row": null,
      "grid_template_areas": null,
      "grid_template_columns": null,
      "grid_template_rows": null,
      "height": null,
      "justify_content": null,
      "justify_items": null,
      "left": null,
      "margin": null,
      "max_height": null,
      "max_width": null,
      "min_height": null,
      "min_width": null,
      "object_fit": null,
      "object_position": null,
      "order": null,
      "overflow": null,
      "overflow_x": null,
      "overflow_y": null,
      "padding": null,
      "right": null,
      "top": null,
      "visibility": null,
      "width": null
     }
    },
    "d932478815ad4ee58a672fb1ee59e121": {
     "model_module": "@jupyter-widgets/controls",
     "model_name": "ProgressStyleModel",
     "model_module_version": "1.5.0",
     "state": {
      "_model_module": "@jupyter-widgets/controls",
      "_model_module_version": "1.5.0",
      "_model_name": "ProgressStyleModel",
      "_view_count": null,
      "_view_module": "@jupyter-widgets/base",
      "_view_module_version": "1.2.0",
      "_view_name": "StyleView",
      "bar_color": null,
      "description_width": ""
     }
    },
    "6675b30a4ef946e399e9ccdb98b004ea": {
     "model_module": "@jupyter-widgets/base",
     "model_name": "LayoutModel",
     "model_module_version": "1.2.0",
     "state": {
      "_model_module": "@jupyter-widgets/base",
      "_model_module_version": "1.2.0",
      "_model_name": "LayoutModel",
      "_view_count": null,
      "_view_module": "@jupyter-widgets/base",
      "_view_module_version": "1.2.0",
      "_view_name": "LayoutView",
      "align_content": null,
      "align_items": null,
      "align_self": null,
      "border": null,
      "bottom": null,
      "display": null,
      "flex": null,
      "flex_flow": null,
      "grid_area": null,
      "grid_auto_columns": null,
      "grid_auto_flow": null,
      "grid_auto_rows": null,
      "grid_column": null,
      "grid_gap": null,
      "grid_row": null,
      "grid_template_areas": null,
      "grid_template_columns": null,
      "grid_template_rows": null,
      "height": null,
      "justify_content": null,
      "justify_items": null,
      "left": null,
      "margin": null,
      "max_height": null,
      "max_width": null,
      "min_height": null,
      "min_width": null,
      "object_fit": null,
      "object_position": null,
      "order": null,
      "overflow": null,
      "overflow_x": null,
      "overflow_y": null,
      "padding": null,
      "right": null,
      "top": null,
      "visibility": null,
      "width": null
     }
    },
    "ecc38d1eb03148f1b8115c36e80e279f": {
     "model_module": "@jupyter-widgets/controls",
     "model_name": "DescriptionStyleModel",
     "model_module_version": "1.5.0",
     "state": {
      "_model_module": "@jupyter-widgets/controls",
      "_model_module_version": "1.5.0",
      "_model_name": "DescriptionStyleModel",
      "_view_count": null,
      "_view_module": "@jupyter-widgets/base",
      "_view_module_version": "1.2.0",
      "_view_name": "StyleView",
      "description_width": ""
     }
    }
   }
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
